package cn.jslancer.webx.request;

import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import org.apache.commons.collections4.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author zhuangchao
 * @date 2019/12/27 11:12
 */
public class WebxRequest implements ServerRequest {

    private String url;
    private String method;
    private String path;

    private FullHttpRequest request;

    private HttpHeaders headers;

    private Map<String, List<String>> parameters;

    private Map<String, String> forms;

    private Map<String, Object> attributes = new HashMap<>();

    public WebxRequest(FullHttpRequest request) {
        url = request.uri();
        method = request.method().name();
        this.request = request;
        this.headers = request.headers();
    }


    @Override
    public String getPath() {
        if (path == null) {
            initParams();
        }
        return this.path;
    }

    @Override
    public String getUrl() {
        return this.url;
    }

    @Override
    public String getMethod() {
        return this.method;
    }

    @Override
    public String getParam(String name) {
        if (parameters == null) {
            initParams();
        }
        List<String> list = parameters.get(name);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    @Override
    public String getPost(String name) {
        if (forms == null) {
            initPost();
        }
        return forms.get(name);
    }

    @Override
    public List<String> getParams(String name) {
        return this.parameters.get(name);
    }

    private void initParams() {
        QueryStringDecoder decoder = new QueryStringDecoder(url);
        this.parameters = decoder.parameters();
        this.path = decoder.path();
    }

    private void initPost() {
        forms = new HashMap<>();
        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
        List<InterfaceHttpData> bodyHttpDatas = decoder.getBodyHttpDatas();
        for (InterfaceHttpData httpData : bodyHttpDatas) {
            if (httpData.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                MemoryAttribute attribute = (MemoryAttribute) httpData;
                forms.put(attribute.getName(), attribute.getValue());
            } else {
                String name = httpData.getName();
                System.out.println(name);
            }
        }
    }

    @Override
    public Object getAttribute(String name) {
        return this.attributes.get(name);
    }

    @Override
    public void setAttribute(String name, Object value) {
        this.attributes.put(name, value);
    }

    @Override
    public Map<String, Object> getAttributes() {
        return this.attributes;
    }


    @Override
    public int getContentLength() {
        return this.headers.getInt(HttpHeaderNames.CONTENT_LENGTH.toString());
    }

    @Override
    public String getContentType() {
        return this.headers.get(HttpHeaderNames.CONTENT_TYPE.toString());
    }

    @Override
    public <T> T bodyParse(Class<T> cls) {
        ByteBuf content = request.content();
        if (content.readableBytes() == 0) {
            return null;
        }
        byte[] bytes = new byte[content.readableBytes()];
        return JSON.parseObject(bytes, cls);
    }
}
